﻿package org.flashdevelop.utils
{
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;
    import flash.xml.*;

    public class FlashConnect extends Object
    {
        public static var onReturnData:Function;
        public static var port:Number = 1978;
        private static var interval:Number;
        private static var messages:Array;
        public static var onConnection:Function;
        public static var host:String = "127.0.0.1";
        public static var status:Number = 0;
        private static var socket:XMLSocket;
        public static var limit:Number = 1000;
        private static var counter:Number;

        public function FlashConnect()
        {
            return;
        }// end function

        private static function onIOError(event:IOErrorEvent) : void
        {
            FlashConnect.status = -1;
            if (FlashConnect.onConnection != null)
            {
                FlashConnect.onConnection();
            }
            return;
        }// end function

        public static function atrace(... args) : void
        {
          var _args:String = args.join(",");
          var _loc_3:* = createMsgNode(_args, TraceLevel.DEBUG);
            FlashConnect.send(_loc_3);
            return;
        }// end function

        private static function createMsgNode(param1:String, param2:Number) : XMLNode
        {
            if (isNaN(param2))
            {
                param2 = TraceLevel.DEBUG;
            }
            var _loc_3:* = new XMLNode(1, null);
            var _loc_4:* = new XMLNode(3, encodeURI(param1));
            _loc_3.attributes.state = param2.toString();
            _loc_3.attributes.cmd = "trace";
            _loc_3.nodeName = "message";
            _loc_3.appendChild(_loc_4);
            return _loc_3;
        }// end function

        public static function send(param1:XMLNode) : void
        {
            if (messages == null)
            {
                initialize();
            }
            messages.push(param1);
            return;
        }// end function

        private static function onSecurityError(event:SecurityErrorEvent) : void
        {
            FlashConnect.status = -1;
            if (FlashConnect.onConnection != null)
            {
                FlashConnect.onConnection();
            }
            return;
        }// end function

        public static function flush() : Boolean
        {
            if (status)
            {
                sendStack();
                return true;
            }
            return false;
        }// end function

        public static function trace(param1:Object, param2:Number = 1) : void
        {
            var _loc_3:* = createMsgNode(param1.toString(), param2);
            FlashConnect.send(_loc_3);
            return;
        }// end function

        private static function onConnect(event:Event) : void
        {
            FlashConnect.status = 1;
            if (FlashConnect.onConnection != null)
            {
                FlashConnect.onConnection();
            }
            return;
        }// end function

        public static function initialize() : int
        {
            if (socket)
            {
                return status;
            }
            counter = 0;
            messages = new Array();
            socket = new XMLSocket();
            socket.addEventListener(Event.CLOSE, onClose);
            socket.addEventListener(DataEvent.DATA, onData);
            socket.addEventListener(Event.CONNECT, onConnect);
            socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
            socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
            interval = setInterval(sendStack, 50);
            socket.connect(host, port);
            return status;
        }// end function

        private static function onClose(event:Event) : void
        {
            socket = null;
            FlashConnect.status = -1;
            if (FlashConnect.onConnection != null)
            {
                FlashConnect.onConnection();
            }
            return;
        }// end function

        private static function sendStack() : void
        {
            var _loc_1:XMLDocument = null;
            var _loc_2:XMLNode = null;
            var _loc_3:String = null;
            var _loc_4:XMLNode = null;
            var _loc_5:XMLNode = null;
            if (messages.length > 0 && status == 1)
            {
                _loc_1 = new XMLDocument();
                _loc_2 = _loc_1.createElement("flashconnect");
                while (messages.length != 0)
                {
                    
                    var _loc_7:* = counter + 1;
                    counter = _loc_7;
                    if (counter > limit)
                    {
                        clearInterval(interval);
                        _loc_3 = new String("FlashConnect aborted. You have reached the limit of maximum messages.");
                        _loc_4 = createMsgNode(_loc_3, TraceLevel.ERROR);
                        _loc_2.appendChild(_loc_4);
                        messages = new Array();
                        break;
                        continue;
                    }
                    _loc_5 = XMLNode(messages.shift());
                    _loc_2.appendChild(_loc_5);
                }
                _loc_1.appendChild(_loc_2);
                if (socket && socket.connected)
                {
                    socket.send(_loc_1);
                }
                counter = 0;
            }
            return;
        }// end function

        private static function onData(event:DataEvent) : void
        {
            FlashConnect.status = 1;
            if (FlashConnect.onReturnData != null)
            {
                FlashConnect.onReturnData(event.data);
            }
            return;
        }// end function

        public static function mtrace(param1:Object, param2:String, param3:String, param4:Number) : void
        {
            var _loc_5:* = param3.split("/").join("\\");
            var _loc_6:* = param3.split("/").join("\\") + ":" + param4 + ":" + param1;
            FlashConnect.trace(_loc_6, TraceLevel.DEBUG);
            return;
        }// end function

    }
}
